/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef RELATIONAL_STORE_H
#define RELATIONAL_STORE_H

/**
 * @addtogroup RDB
 * @{
 *
 * @brief The relational database (RDB) store manages data based on relational models.
 * A complete set of mechanisms for managing local databases is provided based on the underlying SQLite.
 * To satisfy different needs in complicated scenarios, the RDB module provides a series of methods for performing
 * operations such as adding, deleting, modifying, and querying data, and supports direct execution of SQL statements.
 *
 * @syscap SystemCapability.DistributedDataManager.RelationalStore.Core
 * @since 10
 */


/**
 * @file relational_store.h
 *
 * @brief Provides methods for managing relational database (RDB) stores.
 * @library native_rdb_ndk_header.so
 * @since 10
 */

#include "oh_cursor.h"
#include "oh_predicates.h"
#include "oh_value_object.h"
#include "oh_values_bucket.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief Enumerates the RDB store security levels.
 *
 * @since 10
 */
typedef enum OH_Rdb_SecurityLevel {
    /**
     * @brief S1: indicates the low security level.
     *
     * If data leakage occurs, minor impact will be caused.
     */
    S1 = 1,
    /**
     * @brief S2: indicates the medium security level.
     *
     * If data leakage occurs, moderate impact will be caused.
     */
    S2,
    /**
     * @brief S3: indicates the high security level.
     *
     If data leakage occurs, major impact will be caused.
     */
    S3,
    /**
     * @brief S4: indicates the critical security level.
     *
     * If data leakage occurs, critical impact will be caused.
     */
    S4
} OH_Rdb_SecurityLevel;

/**
 * @brief Defines the RDB store configuration.
 *
 * @since 10
 */
#pragma pack(1)
typedef struct {
    /** Size of the struct. */
    int selfSize;
    /** Database file path. */
    const char *dataBaseDir;
    /** RDB store name. */
    const char *storeName;
    /** Application bundle name. */
    const char *bundleName;
    /** Application module name. */
    const char *moduleName;
    /** Whether to encrypt the RDB store. */
    bool isEncrypt;
    /** RDB store security level. For details, see {@link OH_Rdb_SecurityLevel}. */
    int securityLevel;
} OH_Rdb_Config;
#pragma pack()

/**
 * @brief Defines the database type.
 *
 * @since 10
 */
typedef struct {
    /** Unique identifier of the OH_Rdb_Store struct. */
    int64_t id;
} OH_Rdb_Store;

/**
 * @brief Creates an {@link OH_VObject} instance.
 *
 * @return Returns the pointer to the {@link OH_VObject} instance created if the operation is successful;
 * returns NULL otherwise.
 * @see OH_VObject.
 * @since 10
 */
OH_VObject *OH_Rdb_CreateValueObject(void);

/**
 * @brief Creates an {@link OH_VBucket} instance.
 *
 * @return Returns the pointer to the {@link OH_VBucket} instance created if the operation is successful;
 * returns NULL otherwise.
 * @see OH_VBucket.
 * @since 10
 */
OH_VBucket *OH_Rdb_CreateValuesBucket(void);

/**
 * @brief Creates an {@link OH_Predicates} instance.
 *
 * @param table Indicates the pointer to the name of the database table.
 * @return Returns the pointer to the {@link OH_Predicates} instance created if the operation is successful;
 * returns NULL otherwise.
 * @see OH_Predicates.
 * @since 10
 */
OH_Predicates *OH_Rdb_CreatePredicates(const char *table);

/**
 * @brief Obtains an {@link OH_Rdb_Store} instance for RDB store operations.
 *
 * @param config Indicates the pointer to the {@link OH_Rdb_Config} instance, which is the RDB store configuration.
 * @param errCode Indicates the pointer to the function execution status.
 * @return Returns the pointer to the {@link OH_Rdb_Store} instance created if the operation is successful;
 * returns NULL otherwise.
 * @see OH_Rdb_Config, OH_Rdb_Store.
 * @since 10
 */
OH_Rdb_Store *OH_Rdb_GetOrOpen(const OH_Rdb_Config *config, int *errCode);

/**
 * @brief Destroys a {@link OH_Rdb_Store} instance and reclaims the memory occupied.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_CloseStore(OH_Rdb_Store *store);

/**
 * @brief Deletes an RDB store based on the specified database file configuration.
 *
 * @param path Indicates the pointer to the database file path.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @since 10
 */
int OH_Rdb_DeleteStore(const OH_Rdb_Config *config);

/**
 * @brief Insert a row of data into a table.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param table Indicates the pointer to the name of the target table.
 * @param valuesBucket Indicates the pointer to the data row {@link OH_VBucket} to insert.
 * @return Returns the row ID if the operation is successful; returns an error code otherwise.
 * @see OH_Rdb_Store, OH_VBucket.
 * @since 10
 */
int OH_Rdb_Insert(OH_Rdb_Store *store, const char *table, OH_VBucket *valuesBucket);

/**
 * @brief Updates data in an RDB store based on specified conditions.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param valuesBucket Indicates the pointer to the data {@link OH_VBucket} to be written to the table.
 * @param predicates Indicates the pointer to the {@link OH_Predicates} instance, which specifies the update conditions.
 * @return Returns the number of updated rows if the operation is successful; returns an error code otherwise.
 * @see OH_Rdb_Store, OH_Bucket, OH_Predicates.
 * @since 10
 */
int OH_Rdb_Update(OH_Rdb_Store *store, OH_VBucket *valuesBucket, OH_Predicates *predicates);

/**
 * @brief Deletes data from an RDB store based on specified conditions.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param predicates Indicates the pointer to the {@link OH_Predicates} instance, which specifies the deletion
 * conditions.
 * @return Returns the number of rows deleted if the operation is successful; returns an error code otherwise.
 * @see OH_Rdb_Store, OH_Predicates.
 * @since 10
 */
int OH_Rdb_Delete(OH_Rdb_Store *store, OH_Predicates *predicates);

/**
 * @brief Queries data in an RDB store based on specified conditions.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param predicates Indicates the pointer to the {@link OH_Predicates} instance, which specifies the query conditions.
 * @param columnNames Indicates the pointer to the columns to be queried. If this parameter is not specified,
 * the query applies to all columns.
 * @param length Indicates the length of the <b>columnNames</b> array.
 * @return Returns the pointer to the {@link OH_Cursor} instance if the operation is successful; returns NULL otherwise.
 * @see OH_Rdb_Store, OH_Predicates, OH_Cursor.
 * @since 10
 */
OH_Cursor *OH_Rdb_Query(OH_Rdb_Store *store, OH_Predicates *predicates, const char *const *columnNames, int length);

/**
 * @brief Executes an SQL statement that contains specified arguments but returns no value.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param sql Indicates the pointer to the SQL statement to execute.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_Execute(OH_Rdb_Store *store, const char *sql);

/**
 * @brief Executes the SQL statement to query data in an RDB store.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param sql Indicates the pointer to the SQL statement to execute.
 * @return Returns the pointer to the {@link OH_Cursor} instance if the operation is successful; returns NULL otherwise.
 * @see OH_Rdb_Store.
 * @since 10
 */
OH_Cursor *OH_Rdb_ExecuteQuery(OH_Rdb_Store *store, const char *sql);

/**
 * @brief Starts the transaction before executing an SQL statement.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_BeginTransaction(OH_Rdb_Store *store);

/**
 * @brief Rolls back the SQL statements executed.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_RollBack(OH_Rdb_Store *store);

/**
 * @brief Submits the SQL statements executed.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_Commit(OH_Rdb_Store *store);

/**
 * @brief Backs up an RDB store in the specified directory.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param databasePath Indicates the pointer to the backup file path of the database.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_Backup(OH_Rdb_Store *store, const char *databasePath);

/**
 * @brief Restores an RDB store from the specified database backup file.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param databasePath Indicates the pointer to the backup file path of the database.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_Restore(OH_Rdb_Store *store, const char *databasePath);

/**
 * @brief Obtains the RDB store version.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param version Indicates the pointer to the version number.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_GetVersion(OH_Rdb_Store *store, int *version);

/**
 * @brief Sets the RDB store version.
 *
 * @param store Indicates the pointer to the {@link OH_Rdb_Store} instance.
 * @param version Indicates the version to set.
 * @return Returns the operation result. If the operation fails, an error code is returned.
 * @see OH_Rdb_Store.
 * @since 10
 */
int OH_Rdb_SetVersion(OH_Rdb_Store *store, int version);

#ifdef __cplusplus
};
#endif

#endif // RELATIONAL_STORE_H
